package se.ytterman.jserial.util;

import java.lang.*;
import java.util.*;
import java.lang.reflect.*;

public class InstanceFactory {
    // Object instance factory (Constructor without parameters)
    public static Object newInstance(String className,
                                     boolean debug) {
        // Define result variable
        Object result = null;

        try {
            // Get class reference
            Class dynamicClass = Class.forName(className);

            // Get a list of constructors
            Constructor[] classConstructors = dynamicClass.getConstructors();

            // Declare result container
            Constructor classConstructor = null;

            // Iterate over the constructor list....
            for(int i = 0; i < classConstructors.length; i++) {
                // Get the present constructor
                classConstructor = classConstructors[i];

                // Fetch declared constructor parameters
                Class[] declaredParameterTypes = classConstructor.getParameterTypes();
                
                // Check for firts constructor without parameters
                if(declaredParameterTypes.length == 0) {
                    // Debug message
                    if(debug)
                        System.out.println("Executing: " + classConstructor.toGenericString());

                    // Run constructor...
                    result = classConstructor.newInstance(null);
                }
            }
        }
        catch(Exception e) {
            System.out.println(e + " : " + e.getMessage());
        }

        // Return object instance on success
        return result;
    }
        
    // Object instance factory (Constructor with parameters)
    public static Object newInstance(String className,
                                     Object[] constructorParameters,
                                     boolean debug) {
        // Define result variable
        Object result = null;

        try {
            // Get class reference
            Class dynamicClass = Class.forName(className);

            // Get a list of constructors
            Constructor[] classConstructors = dynamicClass.getConstructors();

            // Declare result container
            Constructor classConstructor = null;

            // Iterate over the constructor list....
            for(int i = 0; i < classConstructors.length; i++) {
                // Get the present constructor
                classConstructor = classConstructors[i];

                // Fetch declared constructor parameters
                Class[] declaredParameterTypes = classConstructor.getParameterTypes();

                // Build paramter type array
                Class[] valueParameterTypes = new Class[constructorParameters.length];

                // Iterate over the parameters
                for(int j = 0; j < constructorParameters.length; j++)
                    valueParameterTypes[j] = constructorParameters[j].getClass();

                // Compare class arrays
                if(Arrays.equals(declaredParameterTypes, valueParameterTypes)) {
                    // Debug message
                    if(debug)
                        System.out.println("Executing: " + classConstructor.toGenericString());

                    // Run constructor...
                    result = classConstructor.newInstance(constructorParameters);
                }
            }
        }
        catch(Exception e) {
            System.out.println(e + " : " + e.getMessage());
        }

        // Return object instance on success
        return result;
    }
}
